package cn.stylefeng.guns.modular.business.service.impl;

import cn.stylefeng.guns.api.core.exception.RestExceptionEnum;
import cn.stylefeng.guns.api.core.util.JwtTokenUtil;
import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.guns.config.redis.redis.util.Redishandler0;
import cn.stylefeng.guns.core.MessageNoticeType;
import cn.stylefeng.guns.core.MoneyLogType;
import cn.stylefeng.guns.core.RecoverConst;
import cn.stylefeng.guns.core.UserGradeLevel;
import cn.stylefeng.guns.modular.business.common.Constants;
import cn.stylefeng.guns.modular.business.common.TokenSingleton;
import cn.stylefeng.guns.modular.business.entity.*;
import cn.stylefeng.guns.modular.business.mapper.MoneyLogMapper;
import cn.stylefeng.guns.modular.business.mapper.UserPropertyMapper;
import cn.stylefeng.guns.modular.business.model.dto.BindingUserInfoDTO;
import cn.stylefeng.guns.modular.business.model.params.MessageDTO;
import cn.stylefeng.guns.modular.business.model.params.MessageType;
import cn.stylefeng.guns.modular.business.model.params.UserTeamParam;
import cn.stylefeng.guns.modular.business.model.params.WxMessageDTO;
import cn.stylefeng.guns.modular.business.model.result.*;
import cn.stylefeng.guns.modular.business.service.*;
import cn.stylefeng.guns.sms.core.enums.SmsSendSource;
import cn.stylefeng.guns.sms.core.enums.SmsSendStatus;
import cn.stylefeng.guns.sms.core.enums.SmsTemplateCode;
import cn.stylefeng.guns.sms.core.sms.SmsManager;
import cn.stylefeng.guns.sms.modular.entity.SmsInfo;
import cn.stylefeng.guns.sys.core.constant.Const;
import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.guns.sys.core.util.*;
import cn.stylefeng.guns.sys.modular.system.entity.Dict;
import cn.stylefeng.guns.sys.modular.system.entity.DictType;
import cn.stylefeng.guns.sys.modular.system.entity.Role;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.factory.UserFactory;
import cn.stylefeng.guns.sys.modular.system.mapper.UserMapper;
import cn.stylefeng.guns.sys.modular.system.model.UserDto;
import cn.stylefeng.guns.sys.modular.system.service.DictService;
import cn.stylefeng.guns.sys.modular.system.service.DictTypeService;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weixin.popular.api.SnsAPI;
import weixin.popular.api.TokenAPI;
import weixin.popular.api.UserAPI;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 用户属性表 服务实现类
 * </p>
 *
 * @author jwj
 * @since 2019-07-19
 */
@Service
@Slf4j
public class AccountServiceImpl extends ServiceImpl<UserMapper, User> implements AccountService {

    @Autowired
    private UserService userService;

    @Autowired
    private Redishandler0 redishandler0;

    @Autowired
    private UserPropertyService userPropertyService;

    @Autowired
    private UserGradeService userGradeService;

    @Autowired
    private DictService dictService;

    @Autowired
    private DictTypeService dictTypeService;

    @Autowired
    private SmsManager smsManager;

    @Autowired
    private CertificationService certificationService;

    @Autowired
    MessageService messageService;

    @Autowired
    private MessageNoticeService messageNoticeService;


    @Value("${file.uploadUrl}")
    private String uploadPreUrl;

    /**
     *
     */
    @Autowired
    private MoneyLogService moneyLogService;

    @Autowired
    private MoneyLogMapper moneyLogMapper;

    @Autowired
    private UserPropertyMapper userPropertyMapper;

    /**
     * 微信appid
     */
    @Value("${wx.appid}")
    private String appId;


    /**
     * 微信秘钥
     */
    @Value("${wx.appsecret}")
    private String appSecret;

    /**
     * 注册
     *
     * @param param
     * @author jwj
     * @Date 2019-07-18
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public User reg(UserDto param) {
        // 判断账号是否重复
        User theUser = userService.getByAccount(param.getAccount());
        if (theUser != null) {
            throw new ServiceException(BizExceptionEnum.USER_ALREADY_REG);
        }
        if (!invalidSMS(param.getAccount(), param.getSmsCode())) {
            throw new ServiceException(500, "验证码过错误或过期");
        }
        Optional.ofNullable(param.getRefeeInfo()).filter(scs -> StringUtils.isNotEmpty(scs)).orElseThrow(() -> new ServiceException(702, "无推荐用户，暂不支持自主注册"));

        // 完善账号信息
        String salt = ShiroKit.getRandomSalt(5);
        String password = ShiroKit.md5(param.getPassword(), salt);
        User newUser = UserFactory.createUser(param, password, salt);
        String gunsWebAccountDeptId = (String) ConstantsContext.getConstntsMap().get("GUNS_WEB_ACCOUNT_DEPT");
        newUser.setDeptId(Long.valueOf(gunsWebAccountDeptId));
        //分配前端用户角色
        String gunsWebAccountRoleKey = (String) ConstantsContext.getConstntsMap().get("GUNS_WEB_ROLE");
        String roleStr = redishandler0.getHash(Const.SYS_ROLE_KEY, "", gunsWebAccountRoleKey);
        if (StringUtils.isNotEmpty(roleStr)) {
            Role role = JSONObject.parseObject(roleStr, Role.class);
            newUser.setRoleId(role.getRoleId().toString());
        }
        if (ValidateUtils.isPhone(param.getAccount())) {
            newUser.setPhone(param.getAccount());
        }
        newUser.setOpenid(param.getOpenid());
        newUser.setRefeeInfo(IdGen.randomString(6));
        newUser.setAmount(new BigDecimal(0));
        newUser.setMessagePush("0");
        userService.save(newUser);
        //处理推荐关系
        boolean result = saveRecommendRelation(newUser, param.getRefeeInfo());
        if (!result) {
            throw new ServiceException(RestExceptionEnum.GRADE_SAVE_ERROR);
        }
        return newUser;
    }

    /**
     * 新增
     *
     * @author jwj
     * @Date 2019-07-18
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public User wxReg(UserDto param) {

        // 判断账号是否重复
        Integer count = baseMapper.selectCount(new QueryWrapper<User>().eq("openid", param.getOpenid()));
        if (count > 0) {
            throw new ServiceException(BizExceptionEnum.USER_ALREADY_REG);
        }
        // 完善账号信息
        //密码改用前端传入
        String pass = param.getPassword();
        String salt = ShiroKit.getRandomSalt(5);
        String password = ShiroKit.md5(pass, salt);
        User newUser = UserFactory.createUser(param, password, salt);
        // 完善账号信息
        String gunsWebAccountDeptId = (String) ConstantsContext.getConstntsMap().get("GUNS_WEB_ACCOUNT_DEPT");
        newUser.setDeptId(Long.valueOf(gunsWebAccountDeptId));
        //分配前端用户角色
        String gunsWebAccountRoleKey = (String) ConstantsContext.getConstntsMap().get("GUNS_WEB_ROLE");
        String roleStr = redishandler0.getHash(Const.SYS_ROLE_KEY, "", gunsWebAccountRoleKey);
        if (StringUtils.isNotEmpty(roleStr)) {
            Role role = JSONObject.parseObject(roleStr, Role.class);
            newUser.setRoleId(role.getRoleId().toString());
        }
        newUser.setName(param.getName());
        newUser.setAvatar(param.getAvatar());
        newUser.setSex(param.getSex());
        newUser.setOpenid(param.getOpenid());
        newUser.setRefeeInfo(IdGen.randomString(6));
        newUser.setAmount(new BigDecimal(0));
        newUser.setMessagePush("0");
        userService.save(newUser);
        //处理推荐关系
        boolean result = saveRecommendRelationByUserId(newUser, param.getRefeeUserId());
        if (!result) {
            throw new ServiceException(RestExceptionEnum.GRADE_SAVE_ERROR);
        }
        return newUser;
    }

    /**
     * 保存推荐关系
     *
     * @param accountInfo 账号信息
     * @param userId      上级用户
     * @return boolean
     */
    private boolean saveRecommendRelationByUserId(User accountInfo, Long userId) {
        UserProperty recommendUser = new UserProperty();
        recommendUser.setUserId(accountInfo.getUserId());
        if (userId != null) {
            User parentAccount = getById(userId);
            if (parentAccount != null) {
                UserProperty recommendUser1 = userPropertyService.getOne(new QueryWrapper<UserProperty>().eq("user_id", parentAccount.getUserId()).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE));
                recommendUser.setParentId(parentAccount.getUserId());
                recommendUser.setParentGradeId(recommendUser1.getGradeId());
                if (StringUtils.isNotEmpty(recommendUser1.getRelationPath())) {
                    recommendUser.setRelationPath(recommendUser1.getRelationPath() + "-" + parentAccount.getUserId());
                    recommendUser.setRecommendLevel(recommendUser1.getRecommendLevel() + 1);
                    //设置初始等级为1级
                    UserGrade grade = getGrade(UserGradeLevel.first_level.getCode());
                    recommendUser.setGradeId(grade.getGradeId());
                    recommendUser.setGradeLevel(grade.getLevel());
                } else {
                    recommendUser.setRelationPath(parentAccount.getUserId() + "");
                    recommendUser.setRecommendLevel(RecoverConst.USER_GRADE_LEVEL_FIRST);

                    //设置内置用户推荐的人初始等级为vip会员
                    UserGrade grade = getGrade(UserGradeLevel.second_level.getCode());
                    recommendUser.setGradeId(grade.getGradeId());
                    recommendUser.setGradeLevel(grade.getLevel());
                }

                //给推荐者发送新用户加入通知
                if (parentAccount.getMessagePush().equals("0")) {
                    sendMessageToRecommender(accountInfo, parentAccount);
                    //发送系统消息
                    messageNoticeService.add("恭喜您成功邀请一位新会员", "恭喜你，邀请" + accountInfo.getName() + "成功。努力推广，您的佣金也会相应提高哦", MessageNoticeType.system.getCode(), parentAccount.getUserId());
                }
            } else {
                throw new ServiceException(500, "请先取消关注一次，然后再次关注");
            }
        }
        recommendUser.setUserId(accountInfo.getUserId());
        return userPropertyService.save(recommendUser);
    }

    /**
     * 保存推荐关系
     *
     * @param accountInfo 账号信息
     * @param refereeInfo 推荐码
     * @return boolean
     */
    private boolean saveRecommendRelation(User accountInfo, String refereeInfo) {
        UserProperty recommendUser = new UserProperty();
        recommendUser.setUserId(accountInfo.getUserId());
        if (StringUtils.isNotBlank(refereeInfo)) {
            User parentAccount = userService.getOne(new QueryWrapper<User>().eq("refee_info", refereeInfo).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE));
            if (parentAccount != null) {
                UserProperty recommendUser1 = userPropertyService.getOne(new QueryWrapper<UserProperty>().eq("user_id", parentAccount.getUserId()).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE));
                recommendUser.setParentId(parentAccount.getUserId());
                recommendUser.setParentGradeId(recommendUser1.getGradeId());
                if (StringUtils.isNotEmpty(recommendUser1.getRelationPath())) {
                    recommendUser.setRelationPath(recommendUser1.getRelationPath() + "-" + parentAccount.getUserId());
                    recommendUser.setRecommendLevel(recommendUser1.getRecommendLevel() + 1);
                    //设置初始等级为1级
                    UserGrade grade = getGrade(UserGradeLevel.first_level.getCode());
                    recommendUser.setGradeId(grade.getGradeId());
                    recommendUser.setGradeLevel(grade.getLevel());
                } else {
                    recommendUser.setRelationPath(parentAccount.getUserId() + "");
                    recommendUser.setRecommendLevel(RecoverConst.USER_GRADE_LEVEL_FIRST);

                    //设置内置用户推荐的人初始等级为vip会员
                    UserGrade grade = getGrade(UserGradeLevel.second_level.getCode());
                    recommendUser.setGradeId(grade.getGradeId());
                    recommendUser.setGradeLevel(grade.getLevel());
                }
                //给推荐者发送新用户加入通知
                if (parentAccount.getMessagePush().equals("0")) {
                    sendMessageToRecommender(accountInfo, parentAccount);
                }
            } else {
                throw new ServiceException(703, "无推荐用户，暂不支持自主注册");
            }
        }
        recommendUser.setUserId(accountInfo.getUserId());
        return userPropertyService.save(recommendUser);
    }

    private void sendMessageToRecommender(User accountInfo, User parentAccount) {
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setUserIdList(Collections.singletonList(parentAccount.getOpenid()));
        messageDTO.setMessageType(MessageType.NEW_ENTRANT);
        WxMessageDTO wxMessageDTO = new WxMessageDTO();
        wxMessageDTO.setFirst("恭喜您成功邀请了一位新会员" + accountInfo.getName() + ",您的收入即将提高");
        wxMessageDTO.setKeyword1(accountInfo.getAccount());
        //wxMessageDTO.setKeyword2(accountInfo.getName());
        wxMessageDTO.setKeyword2(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        wxMessageDTO.setRemark("努力推广，您的佣金也会相应提高哦");
        messageDTO.setData(wxMessageDTO);
        messageService.sendTemplateMessage(messageDTO);
    }

    private UserGrade getGrade(int level) {
        String gradeStr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "", level + "");
        UserGrade grade = JSONObject.parseObject(gradeStr, UserGrade.class);
        return grade;
    }

    /**
     * 个人信息
     *
     * @param userId
     * @return
     */
    @Override
    public UserInformationResult information(long userId) {
        User user = getUser(userId);
        UserInformationResult userInformationResult = new UserInformationResult();
        ToolUtil.copyProperties(user, userInformationResult);
        //获取用户等级
        UserProperty userProperty = Optional.ofNullable(userPropertyService.getOne(new QueryWrapper<UserProperty>().eq("user_id", userId).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE))).orElse(new UserProperty());
        UserGrade userGrade = getGrade(userProperty.getGradeLevel() == null ? 1 : userProperty.getGradeLevel());
        userInformationResult.setGradeName(Optional.ofNullable(userGrade).orElse(new UserGrade()).getGradeName());
        //实名认证
        Certification certification = certificationService.findByUserId(userId);

        if (null == certification) {
            userInformationResult.setCertification("3");
        } else {
            userInformationResult.setCertification(String.valueOf(certification.getStatus()));
        }
        userInformationResult.setRefeeInfo(user.getRefeeInfo());
        userInformationResult.setGradeLevel(userGrade.getLevel());

        //冲正余额
        //TODO 计算用户余额
        /*BigDecimal totalAmount = moneyLogService.totalAmount(userId);
        if (totalAmount != null && user.getAmount().compareTo(totalAmount) != 0) {
            BigDecimal diffMoney = totalAmount.subtract(user.getAmount());
            MoneyLog moneyLog = new MoneyLog();
            moneyLog.setType(MoneyLogType.SYS_CORRECT.getCode());
            if (user.getAmount().compareTo(totalAmount) > 0) {
                moneyLog.setRemark("系统冲正，给您增加了" + diffMoney.floatValue()+ "元");
                moneyLog.setSecondType(1);
            } else {
                moneyLog.setRemark("系统冲正，减去了您" + diffMoney.floatValue()+ "元");
                moneyLog.setSecondType(2);
            }
            moneyLog.setNewAmount(user.getAmount().add(diffMoney));
            moneyLog.setOldAmount(user.getAmount());
            moneyLog.setUserId(user.getUserId());
            moneyLogService.save(moneyLog);
            //更新账户余额
            user.setAmount(totalAmount);
            user.setUpdateTime(new Date());
            userService.updateById(user);
            userService.update(new UpdateWrapper<User>().setSql("amount=amount+" + diffMoney.floatValue()).eq("user_id", user.getUserId()));
            redishandler0.cacheStringValue(RecoverConst.MONEY_USER_AMOUNT, user.getUserId().toString(), user.getAmount().add(diffMoney).multiply(new BigDecimal(1000)).longValue() + "");
        }*/
        return userInformationResult;
    }

    /**
     * 用户等级信息
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public AccountGradeResult getUserGrade(long userId) {

        AccountGradeResult accountGradeResult = new AccountGradeResult();
        //获取用户等级
        UserProperty userProperty = Optional.ofNullable(userPropertyService.getOne(new QueryWrapper<UserProperty>().eq("user_id", userId).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE))).orElse(new UserProperty());
        UserGrade userGrade = getGrade(userProperty.getGradeLevel() == null ? 1 : userProperty.getGradeLevel());
        accountGradeResult.setGradeName(Optional.ofNullable(userGrade).orElse(new UserGrade()).getGradeName());
        accountGradeResult.setDecrRate(userGrade.getDecrRate());
        accountGradeResult.setGradeId(userGrade.getGradeId());
        accountGradeResult.setGradeLevel(userGrade.getLevel());
        accountGradeResult.setRecommendLevel(userProperty.getRecommendLevel());
        accountGradeResult.setUserId(userId);
        return accountGradeResult;
    }

    private User getUser(long userId) {
        return Optional.ofNullable(userService.getById(userId)).orElseThrow(() -> new ServiceException(BizExceptionEnum.NO_THIS_USER));
    }

    /**
     * 修改用户昵称
     *
     * @param userId 用户id
     * @param name   昵称
     */
    @Override
    public boolean updateName(long userId, String name, String headUrl) {
        User user = new User();
        user.setUserId(userId);
        if (StringUtils.isNotEmpty(name)) {
            user.setName(name);
        }
        user.setAvatar(headUrl);
        return userService.updateById(user);
    }

    /**
     * 接收微信消息推送
     *
     * @param userId      用户id
     * @param messagePush 接收消息推送（0：接收，1：拒绝）
     * @return
     */
    @Override
    public boolean messagePush(long userId, String messagePush) {
        User user = new User();
        user.setUserId(userId);
        user.setMessagePush(messagePush);
        user.setUpdateTime(new Date());
        return userService.updateById(user);
    }

    /**
     * 修改或添加微信号
     *
     * @param userId 用户id
     * @param wxID   微信id
     * @return
     */
    @Override
    public boolean saveWxID(long userId, String wxID) {
        User user = new User();
        user.setUserId(userId);
        user.setWxID(wxID);
        return userService.updateById(user);
    }

    /**
     * 修改手机号
     *
     * @param userId   用户id
     * @param oldPhone 旧手机号
     * @param newPhone 新手机号
     * @param smsCode  验证码
     * @return
     */
    @Override
    public boolean changePhone(long userId, String oldPhone, String newPhone, String smsCode) {
        User user = getUser(userId);
        if (!user.getPhone().equals(oldPhone)) {
            throw new ServiceException(500, "原手机号不存在");
        }
        //TODO 验证码校验
        user.setPhone(newPhone);
        user.setUpdateTime(new Date());

        return userService.updateById(user);
    }

    /**
     * 修改密码
     *
     * @param userId      用户id
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return
     */
    @Override
    public boolean changePassword(long userId, String oldPassword, String newPassword) {
        User user = getUser(userId);
        if (!user.getPassword().equals(ShiroKit.md5(oldPassword, user.getSalt()))) {
            throw new ServiceException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
        }
        String password = ShiroKit.md5(newPassword, user.getSalt());
        user.setPassword(password);
        user.setUpdateTime(new Date());
        return userService.updateById(user);
    }

    /**
     * 修改密码
     *
     * @param account
     * @param password
     * @return
     */
    @Override
    public boolean changePassword(String account, String password) {
        User user = userService.getByAccount(account);
        if (user == null) {
            throw new ServiceException(500, "用户不存在");
        }
        String npassword = ShiroKit.md5(password, user.getSalt());
        user.setPassword(npassword);
        return userService.updateById(user);
    }

    /**
     * 联系我们
     *
     * @return
     */
    @Override
    public List<Dict> contactUs() {
        DictType dictType = Optional.ofNullable(dictTypeService.getOne(new QueryWrapper<DictType>().eq("code", "CONTACT_US"))).orElseThrow(() -> new ServiceException(400, "请先在字典中配置联系我们"));
        return dictService.list(new QueryWrapper<Dict>().eq("dict_type_id", dictType.getDictTypeId()));
    }

    /**
     * 发送短信
     *
     * @param phone
     * @param templateCode
     * @return
     */
    @Override
    public boolean sendSMS(String phone, String templateCode) {
        //SendMessageParam param = new SendMessageParam();
        Map<String, Object> params = new HashMap<>();
        //六位随机码
        String code = IdGenerator.createXCode(6);
        params.put("code", code);
        smsManager.sendSms(phone, templateCode, params);
        SmsInfo smsInfo = new SmsInfo();
        smsInfo.setCreateTime(new Date());
        smsInfo.setPhoneNumbers(phone);
        smsInfo.setStatus(SmsSendStatus.WAITING.getCode());
        smsInfo.setSource(SmsSendSource.WEB.getCode());
        smsInfo.setTemplateCode(templateCode);
        //TODO 保存数据库以后查明细
        redishandler0.cacheStringValue(RecoverConst.REDISPREFIX_CODE, phone, code, RecoverConst.CODE_EXPIRE_TIME);
        return true;
    }

    /**
     * 验证短信
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public boolean invalidSMS(String phone, String code) {
        log.info("开始验证验证码：" + phone);
        //根据缓存获取验证码
        String sendCode = redishandler0.getStringValue(RecoverConst.REDISPREFIX_CODE, phone);
        if (StringUtils.isEmpty(sendCode)) {
            return false;
        }
        if (!sendCode.equals(code)) {
            return false;
        } else {
            //验证成功后，删除验证码
            redishandler0.remove(RecoverConst.REDISPREFIX_CODE, phone);
            return true;

        }
    }

    @Override
    public String getWxToken() {
        try {
            return TokenAPI.token(appId, appSecret).getAccess_token();
        } catch (Exception e) {
            throw new ServiceException(BizExceptionEnum.GET_ACCESS_TOKEN_FAIL);
        }
    }

    @Override
    public String getOpenId(String code) {
        try {
            return SnsAPI.oauth2AccessToken(appId, appSecret, code).getOpenid();
        } catch (Exception e) {
            throw new ServiceException(BizExceptionEnum.GET_OPENID_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BingingResultView binding(BindingUserInfoDTO bindingUserInfoDTO) {
        weixin.popular.bean.user.User user = UserAPI.userInfo(TokenSingleton.getTokenSingleton().getWeixinToken(), bindingUserInfoDTO.getOpenid());
        Optional.ofNullable(user.getQr_scene_str()).filter(scs -> StringUtils.isNotEmpty(scs)).orElseThrow(() -> new ServiceException(702, "无推荐用户，暂不支持自主注册"));
        //注册
        UserDto param = new UserDto();
        param.setAvatar(user.getHeadimgurl());
        param.setName(user.getNickname());
        param.setAccount(bindingUserInfoDTO.getPhone());
        param.setSmsCode(bindingUserInfoDTO.getCode());
        param.setPhone(bindingUserInfoDTO.getPhone());
        param.setOpenid(bindingUserInfoDTO.getOpenid());
        param.setRefeeInfo(bindingUserInfoDTO.getRefeeInfo());
        //密码由前端传入
        param.setPassword(bindingUserInfoDTO.getPwd());
        param.setRefeeUserId(Long.valueOf(user.getQr_scene_str()));
        User reg = wxReg(param);
        String token = JwtTokenUtil.generateToken(String.valueOf(reg.getUserId()));
        BingingResultView bingingResultView = new BingingResultView();
        bingingResultView.setAccount(reg.getAccount());
        bingingResultView.setAccountOpenId(bindingUserInfoDTO.getOpenid());
        bingingResultView.setAccountToken(token);
        bingingResultView.setAccountTokenType("Bearer ");
        bingingResultView.setUserId(reg.getUserId());
        bingingResultView.setNickUserName(reg.getName());
        bingingResultView.setCertificationStatus(3);
        bingingResultView.setRefeeInfo(reg.getRefeeInfo());
        UserGrade userGrade = getGrade(UserGradeLevel.first_level.getCode());
        if (userGrade != null) {
            bingingResultView.setGradeId(userGrade.getGradeId());
            bingingResultView.setGradeLevel(UserGradeLevel.first_level.getCode());
        }
        Integer num = messageNoticeService.count(new QueryWrapper<MessageNotice>().eq("type", 2));
        redishandler0.incr(Constants.UNREAD_MESSAGE_COUNT_KEY, reg.getUserId().toString() + 2, num);
        bingingResultView.setPlatformUnreadMessageCount(num);
        /*Integer systemUnreadMessageCount = Integer.valueOf(redishandler0.getStringValue(Constants.UNREAD_MESSAGE_COUNT_KEY, reg.getUserId().toString() + 1));
        Integer platformUnreadMessageCount = Integer.valueOf(redishandler0.getStringValue(Constants.UNREAD_MESSAGE_COUNT_KEY, reg.getUserId().toString() + 2));
        bingingResultView.setSystemUnreadMessageCount(systemUnreadMessageCount);
        bingingResultView.setPlatformUnreadMessageCount(platformUnreadMessageCount);*/
        return bingingResultView;
    }

    @Override
    public void checkUserBingStatusAndSendMessage(String phone, String openid) {
        //获取用户信息
        Integer count = baseMapper.selectCount(new QueryWrapper<User>().eq("phone", phone).or().eq("openid", openid));
        if (count > 0) {
            throw new ServiceException(BizExceptionEnum.USER_PHONE_HAS_ALREADY_BIND);
        }
        //没有绑定，发短信
        Integer type = SmsTemplateCode.LOGIN.getCode();
        String temCodeKey = SmsTemplateCode.getDescByCode(type);
        String temCode = (String) ConstantsContext.getConstntsMap().get(temCodeKey);
        sendSMS(phone, temCode);
    }


    @Override
    public BingingResultView getAccountTokenWeixin(String openId) {
        User user = baseMapper.selectOne(new QueryWrapper<User>().eq("openid", openId));
        if (user == null) {
            return null;
            //throw new ServiceException(BizExceptionEnum.USER_HAS_NOT_BIND);
        }
        UserProperty userProperty = userPropertyMapper.selectById(user.getUserId());
        String token = JwtTokenUtil.generateToken(String.valueOf(user.getUserId()));
        BingingResultView bingingResultView = new BingingResultView();
        bingingResultView.setAccount(user.getAccount());
        bingingResultView.setAccountOpenId(user.getOpenid());
        bingingResultView.setAccountToken(token);
        bingingResultView.setAccountTokenType("Bearer");
        bingingResultView.setUserId(user.getUserId());
        bingingResultView.setNickUserName(user.getName());
        bingingResultView.setCertificationStatus(user.getCertificationStatus());
        bingingResultView.setRefeeInfo(user.getRefeeInfo());
        if (userProperty != null) {
            bingingResultView.setGradeId(userProperty.getGradeId());
            bingingResultView.setGradeLevel(userProperty.getGradeLevel());
        }
        String systemUnreadMessageCountStr = redishandler0.getStringValue(Constants.UNREAD_MESSAGE_COUNT_KEY, user.getUserId().toString() + 1);
        String platformUnreadMessageCountStr = redishandler0.getStringValue(Constants.UNREAD_MESSAGE_COUNT_KEY, user.getUserId().toString() + 2);
        Integer systemUnreadMessageCount = StringUtils.isNotEmpty(systemUnreadMessageCountStr) ? Integer.valueOf(systemUnreadMessageCountStr) : 0;
        Integer platformUnreadMessageCount = StringUtils.isNotEmpty(platformUnreadMessageCountStr) ? Integer.valueOf(platformUnreadMessageCountStr) : 0;
        bingingResultView.setSystemUnreadMessageCount(systemUnreadMessageCount);
        bingingResultView.setPlatformUnreadMessageCount(platformUnreadMessageCount);
        return bingingResultView;
    }

    /**
     * 获取我的团队汇总
     *
     * @param userId
     * @return
     */
    @Override
    public UserTeamResult getMyTeamTotal(Long userId) {
        UserTeamResult userTeamResult = new UserTeamResult();
        userTeamResult.setTeamNum(userPropertyMapper.getMyTeamTotal(userId));
        userTeamResult.setAmount(moneyLogMapper.getMyTeamTotal(userId));
        UserProperty userProperty = userPropertyMapper.selectById(userId);

        String gradeStr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "", userProperty.getGradeLevel() + "");
        UserGrade grade = JSONObject.parseObject(gradeStr, UserGrade.class);
        userTeamResult.setGradeName(grade.getGradeName());
        UserTeamParam userTeamParam = new UserTeamParam();
        userTeamParam.setParentUserId(userId);

        Long zTeamNum = userPropertyMapper.getMyPushCount(userTeamParam);
        userTeamResult.setZPushNum(zTeamNum);
        userTeamParam = new UserTeamParam();
        userTeamParam.setParentPushUserId(userId);
        Long jTeamNum = userPropertyMapper.getMyPushCount(userTeamParam);
        userTeamResult.setJPushNum(jTeamNum);
        return userTeamResult;
    }

    /**
     * 获取余额详情
     *
     * @param moneyId
     * @return
     */
    @Override
    public MoneyLogResult getMoneyDetail(Integer moneyId) {
        MoneyLog moneyLog = moneyLogMapper.selectById(moneyId);
        MoneyLogResult moneyLogResult = new MoneyLogResult();
        if (moneyLog != null) {
            ToolUtil.copyProperties(moneyLog, moneyLogResult);
            if (moneyLog.getComeUserId() != null) {
                User comeUser = this.getById(moneyLog.getComeUserId());
                if (StringUtils.isNotEmpty(moneyLog.getRemark())) {
                    moneyLogResult.setRemark(moneyLog.getRemark().replace("realName", comeUser.getRealName()));
                    moneyLogResult.setComeUserRealName(comeUser.getRealName());
                }
            }
        }
        return moneyLogResult;
    }

    /**
     * 获取我的推广图片列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<String> getRefeeImages(Long userId) {
        try {
            User user = userService.getById(userId);
            if (user == null) {
                throw new ServiceException(BizExceptionEnum.NO_THIS_USER);
            }
            String token = TokenSingleton.getTokenSingleton().getWeixinToken();
            String qrcodeUrl = RecoverConst.wxQrcodeUrl;
            qrcodeUrl = String.format(qrcodeUrl, token);
            JSONObject param = new JSONObject();
            param.put("action_name", "QR_LIMIT_STR_SCENE");
            JSONObject scene = new JSONObject();
            JSONObject scene_str = new JSONObject();
            scene_str.put("scene_str", userId.toString());
            scene.put("scene", scene_str);
            param.put("action_info", scene);
            String result = cn.hutool.http.HttpUtil.post(qrcodeUrl, param.toJSONString());
            log.info("开始生成推广二维码，结果：" + result);
            JSONObject json = JSONObject.parseObject(result);
            String texter = json.getString("url");
            Map<String, String> fileParam = new HashMap<>();
            fileParam.put("text", texter);
            fileParam.put("content", "邀请码：" + user.getRefeeInfo());
            fileParam.put("userId", userId.toString());
            String files = HttpUtil.sendPost(uploadPreUrl + "V1.0.0/api/file/upload-refee", fileParam, "utf-8");
            List<String> fileList = JSONArray.parseArray(files, String.class);
            return fileList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取我的平台推广图片列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<String> getPTRefeeImages(Long userId) {
        try {
            User user = userService.getById(userId);
            if (user == null) {
                throw new ServiceException(BizExceptionEnum.NO_THIS_USER);
            }
            if (StringUtils.isEmpty(user.getWxID())) {
                throw new ServiceException(600, "用户没有设置微信，请设置微信");
            }
            Map<String, String> fileParam = new HashMap<>();
            fileParam.put("text", "微信号：" + user.getWxID());
            fileParam.put("userId", userId.toString());
            String files = HttpUtil.sendPost(uploadPreUrl + "V1.0.0/api/file/upload-pt-refee", fileParam, "utf-8");
            List<String> fileList = JSONArray.parseArray(files, String.class);
            return fileList;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
